home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 102_01 / bg.c < prev    next >
Text File  |  1984-02-10  |  19KB  |  786 lines

  1. /*
  2.     Backgammon...finally, some"one" else to play against than just
  3.     my girlfriend, who hates to lose! (but then, so do I...and this
  4.     program doesn't do too bad a job at keeping me honest)
  5.  
  6.     Modified for BDS C by Leor Zolman, 2/82
  7. */
  8.  
  9. #include <bdscio.h>
  10.  
  11. #define H19 1        /* true if to be run on H19 terminal */
  12. #define NIL (-1)
  13. #define MAXGMOV 10
  14. #define MAXIMOVES 1000
  15.  
  16. char level;        /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
  17. int die1;
  18. int die2;
  19. int i;
  20. int j;
  21. int l;
  22. int m;
  23. int count;
  24.  
  25. int red[31];
  26. int white[31];
  27. int probability[13];
  28.  
  29. int imoves;
  30. int goodmoves[MAXGMOV];
  31. int probmoves[MAXGMOV];
  32.  
  33. struct {
  34.     int pos[4];
  35.     int mov[4];
  36. } moves[MAXIMOVES];
  37.  
  38.  
  39. exinit()
  40. {
  41.     int i;
  42.     setmem(externs(), endext() - externs(), 0);
  43.     red[1] = white[1] = 2;
  44.     red[12] = white[12] = 5;
  45.     red[17] = white[17] = 3;
  46.     red[19] = white[19] = 5;
  47.     probability[0] = 0;
  48.     probability[1] = 11;
  49.     probability[2] = 12;
  50.     probability[3] = 13;
  51.     probability[4] = 14;
  52.     probability[5] = 15;
  53.     probability[6] = 16;
  54.     probability[7] = 6;
  55.     probability[8] = 5;
  56.     probability[9] = 4;
  57.     probability[10] = 3;
  58.     probability[11] = 2;
  59.     probability[12] = 1;
  60. }
  61.  
  62. main()
  63. {
  64.     int t,k,n,go[5];
  65.     char c, s[MAXLINE];
  66.     int i;
  67.     int first;    /* true on first move only */
  68.     int mywins, hiswins;
  69.  
  70.     printf("\n\nWelcome to BACKGAMMON!\n");
  71.  
  72.     nrand (0,"Do you need instructions? ");
  73.     if(tolower(getchar())=='y')
  74.         instructions();
  75.     else puts("\n\n");
  76.  
  77.     mywins = hiswins = 0;
  78.  
  79.     printf( "Choose the level of your oppponent:\n");
  80.     printf( "Type 'b' for beginner, or 'i' for intermediate,\n");
  81.     printf( "or anything else to play an expert... ?");
  82.     level='e';
  83.     if((c = tolower(getchar()))=='b') level='b';
  84.     else if(c=='i') level='i';
  85.  
  86.     printf( "\n\nI'll play white, and you'll play red.\n\n");
  87.  
  88. newgame:
  89.     exinit();
  90.     first = 1;
  91.     go[5]=NIL;
  92.  
  93.     printf("Let's throw the dice to see who goes first:\n");
  94.  
  95. throw:    roll();
  96.     printf("I throw: ");
  97.     sleep(15);
  98.     printf("%d, and you throw: ",die1);
  99.     sleep(15);
  100.     printf("%d ... ",die2);
  101.     sleep(15);
  102.     if (die1 == die2) {
  103.         printf("Tied up, so let's try again:\n");
  104.         goto throw;
  105.     }
  106.     printf("%s go first...\n\n", die1 > die2 ? "I" : "You");
  107.     if (die2 > die1) goto nowhmove;
  108.     
  109. whitesmv:
  110.     if (!first) roll();    /* skip roll on first move */
  111.     order();
  112.     first = 0;        /* after this, not first roll anymore */
  113. #if H19
  114.     printf( "\nWhite rolls \33p %d,%d \33q... ",die1,die2);
  115. #else
  116.     printf( "\nWhite rolls %d,%d ... ",die1,die2);
  117. #endif
  118.     if (!chkmov(white,red)) {
  119.         printf("White has no moves. Foo.\n");
  120.         goto nowhmove;
  121.     }
  122.     printf( "White's move is: ");
  123.     if(nextmove(white,red)==NIL)goto nowhmove;
  124.     if(piececount(white,0,24)==0) {
  125.       printf( "\7White wins!\n");
  126.       printf("\nGame score:   Me: %d,  You: %d\n",++mywins,hiswins);
  127.       if (mywins == hiswins)
  128.         printf("All tied up! Who's gonna pull ahead?\n");
  129.       else if (mywins > 2 && !hiswins)
  130.         printf ("It's about time you managed to win a game!\n");
  131.       else switch(nrand(1) % 5) {
  132.         case 4:
  133.         case 0:    printf("Aren't you ashamed? You've been beaten ");
  134.             printf("by a computer...\n");
  135.             break;
  136.         case 1:    printf("Not bad for a dumb program, eh?\n");
  137.             break;
  138.         case 2:    printf("Better luck next time, sucker....\n");
  139.             break;
  140.         case 3:    printf("Maybe you'd better stick to checkers?\n");
  141.             break;
  142.       }
  143.       goto again;
  144.     }
  145.  
  146. nowhmove:
  147.     prtbrd();
  148.     if (!first) roll();        /* skip roll on first move */
  149.     first = 0;            /* after this, not 1st roll anymore */
  150.  
  151. retry:
  152.     order();
  153.  
  154. #if H19
  155.     printf( "Your roll is \33p %d, %d \33q ... ",die1,die2);
  156. #else
  157.     printf( "Your roll is %d,%d ... ",die1,die2);
  158. #endif
  159.     if (!chkmov(red,white)) {
  160.         printf("Sorry, you have no possible moves.\n");
  161.         printf("Type any key to let me make my next move: ");
  162.         getchar();
  163.         goto whitesmv;
  164.     }
  165.  
  166.     printf("your move? ");
  167.     while (!kbhit()) nrand(1);   /* Exercize the random generator while */
  168.     gets(s);             /* waiting for a move to be made...    */
  169.  
  170.     if (ignore_sp(s) == '?' || ignore_sp(s) == 'h') {
  171.       puts("\nType either a list of moves, separated by spaces, or:\n");
  172.       puts("    q -- to quit the current game\n");
  173.       puts("    b -- to see the board\n");
  174.       puts("    ? -- to see these options (h does the same thing)\n");
  175.       puts("Do you want to see the long instructions? ");
  176.       if (tolower(getchar()) == 'y') instructions();
  177.       puts("\n");
  178.       goto retry;
  179.     }
  180.  
  181.     if (ignore_sp(s) == 'q') {    /* check for quit command */
  182.         puts("Are you sure you want to quit? ");
  183.         if (tolower(getchar()) == 'y') goto again;
  184.         putchar('\n');
  185.         goto retry;
  186.     }
  187.  
  188.     if (ignore_sp(s) == 'b') {    /* check for print board command */
  189.         prtbrd();
  190.         goto retry;
  191.     }
  192.                     /* check for null move */
  193.     if( ignore_sp(s) != '-' && !isdigit(ignore_sp(s))) {
  194.         printf("You MUST make a move!\n");
  195.         goto retry;
  196.     }
  197.  
  198.     for (i = 0; s[i]; i++)        /* convert commas to spaces */
  199.      if (s[i] == ',') s[i] = ' ';
  200.  
  201.     n=sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
  202.  
  203.     if( (die1 != die2 && n > 2) || n > 4) {
  204.         printf( "You've made too many moves;\n");
  205.         goto retry;
  206.     }
  207.  
  208.     if( ((die1 != die2) && n < 2) || ((die1 == die2) && n < 4)) {
  209.         if (n == cntred()) goto moveok;
  210.         printf("Are you sure you can't make all the moves? ");
  211.         if (tolower(getchar()) != 'y') {
  212.         printf("\nOK, then let's try it again:\n");
  213.         goto retry;
  214.         }
  215.         putchar('\n');
  216.     }
  217.  
  218. moveok:    go[n]=NIL;
  219.     if(*s=='-'){
  220.         go[0]= -go[0];
  221.         t=die1;
  222.         die1=die2;
  223.         die2=t;
  224.     }
  225.     for(k=0; k<n; k++) {
  226.         if(0<=go[k] && go[k]<=24)continue;
  227.         else{
  228.         printf( "Sorry, move %d is illegal.\n",go[k]);
  229.         goto retry;
  230.         }
  231.     }
  232.     if(play(red,white,go))goto retry;
  233.     if(piececount(red,0,24)==0){
  234.         printf( "\n\7Red wins.\n");
  235.         printf("\nGame score:   Me: %d,  You: %d\n",mywins,++hiswins);
  236.         if (mywins == hiswins)
  237.         printf("Looks like now we're dead even...tiebreaker time!\n");
  238.         else if (hiswins > 2 && !mywins)
  239.         printf("See? I'm not THAT stupid after all!\n");
  240.         else switch(nrand(1) % 5) {
  241.         case 0:    printf( "Congratulations! You've just defeated a ");
  242.             printf( "dumb machine.\n");
  243.             break;
  244.         case 1:    printf("Sigh...at least I put up a good fight, eh?\n");
  245.             break;
  246.         case 2: printf("Darn....I'll get you next time, human!\n");
  247.             break;
  248.         case 3:    printf("Mumble...those unlucky rolls will do it ");
  249.             printf("every time!\n");
  250.             break;
  251.         case 4:    printf("Not bad... for a dumb human!\n");
  252.         }
  253.   again:    printf("\nWould you like to play another game? ");
  254.         if (tolower(getchar()) != 'y') exit();
  255.         printf("\n\n");
  256.         goto newgame;
  257.     }
  258.     goto whitesmv;
  259. }
  260.  
  261. char ignore_sp(s)    /* return first non-whitespace char at s: */
  262. char *s;
  263. {
  264.     char c;
  265.     while (isspace(c = *s++));
  266.     return tolower(c);
  267. }
  268.  
  269. play(player,playee,pos)
  270. int *player,*playee,pos[];
  271. {
  272.     int k,n,die,ipos;
  273.     for(k=0;k<player[0];k++){  /*blots on player[0] must be moved first*/
  274.         if(pos[k]==NIL)break;
  275.         if(pos[k]!=0){
  276.         printf( "\nPiece on BAR (position 0) must be moved first\n");
  277.         return(-1);
  278.         }
  279.     }
  280.     for(k=0;(ipos=pos[k])!=NIL;k++){
  281.         die=k?die2:die1;
  282.         n=25-ipos-die;
  283.         if(player[ipos]==0)goto badmove;
  284.         if(n>0 && playee[n]>=2)goto badmove;
  285.         if(n<=0){
  286.         if(piececount(player,0,18)!=0)goto badmove;
  287.         if((ipos+die)!=25 &&
  288.             piececount(player,19,24-die)!=0)goto badmove;
  289.         }
  290.         player[ipos]--;
  291.         player[ipos+die]++;
  292.     }
  293.     for(k=0;pos[k]!=NIL;k++){
  294.         die=k?die2:die1;
  295.         n=25-pos[k]-die;
  296.         if(n>0 && playee[n]==1){
  297.         playee[n]=0;
  298.         playee[0]++;
  299.         }
  300.     }
  301.     return(0);
  302.  
  303. badmove:
  304.     printf( "Move %d is not legal. Enter all moves again:\n",ipos);
  305.     while(k--){
  306.         die=k?die2:die1;
  307.         player[pos[k]]++;
  308.         player[pos[k]+die]--;
  309.     }
  310.     prtbrd();
  311.     return(-1);
  312. }
  313.  
  314. cntred()            /* count up number of red's pieces */
  315. {
  316.     int i, count;
  317.     for (count = 0, i = 0; i < 25; i++) count += red[i];
  318.     return count;
  319. }
  320.  
  321. chkmov(player,playee)        /* return true if player has possible move */
  322. int *player, *playee;
  323. {
  324.     int k;
  325.     imoves=0;
  326.     movegen(player,playee);
  327.     if(die1!=die2) {
  328.         k = die1;     die1 = die2;    die2 = k;
  329.         movegen(player,playee);
  330.         k = die1;